home *** CD-ROM | disk | FTP | other *** search
- Path: mail2news.demon.co.uk!genesis.demon.co.uk
- From: Lawrence Kirby <fred@genesis.demon.co.uk>
- Newsgroups: comp.lang.c
- Subject: Re: What is &Variable (declared as: char Variable[10])?
- Date: Wed, 28 Feb 96 20:32:50 GMT
- Organization: none
- Message-ID: <825539570snz@genesis.demon.co.uk>
- References: <4gqpa1$3h9@alcor.usc.edu> <4gsdno$1bg@umbc9.umbc.edu> <4gtab6$acb@ceylon.gte.com> <313318b8.53776146@nntp.ix.netcom.com> <4h1u9d$sqq@ceylon.gte.com>
- Reply-To: fred@genesis.demon.co.uk
- X-NNTP-Posting-Host: genesis.demon.co.uk
- X-Newsreader: Demon Internet Simple News v1.27
- X-Mail2News-Path: genesis.demon.co.uk
-
- In article <4h1u9d$sqq@ceylon.gte.com> g051286 "Brenda" writes:
-
- >What is the definition of a pointer?
-
- A pointer is a *type*, more precisely a derived type (which classes it with
- arrays, structures, unions and functions and distinguishes it from integer
- and floating point types which are 'basic types').
-
- > I have always been taught that a
- >pointer is simply an address in memory, and an array name (i.e. myarray)
- >is simply a CONSTANT address. I don't think this statement is all that
- >radical.
-
- It may not be radical but it is unfortunately wrong! :-)
-
- Consider something simple like:
-
- int i = 2;
-
- This is a declaration of an integer variable i. In this case it is also
- a definition because it reserves space for an object (of type int). The object
- is initialised to the value 2. The identifier i is used to reference (or in
- standard terms `designate') the object and as such is termed an lvalue
- (which in C simply means something that designates an object). All objects
- (and also functions) have an address which is, if you like, a handle that can
- be used to refer to the object (as an alternative to an identifier). C
- pointers can hold addresses but they are more than that - they have an
- inherent type (which is visible to the program) and possibly other components
- such as bounds checking information (which is not visible to the program).
- Consider:
-
- int *p = &i;
-
- This defines a pointer variable (i.e. creates an object of type int * and
- declares an identifier p that designates it). &i evaluates to a pointer with
- type int * and value `address of object designated by i' and this is used to
- initialise p. So now we have:
-
- 1. An int object which we can access through the identifier i. The identifier
- is an lvalue so we can write, for example:
-
- i = <expr>;
-
- to change its value.
-
- 2. A value 2 in that object. When we ask the compiler to take the value of an
- expression that designates that object e.g.
-
- printf("%d\n", i)
-
- the result will be 2.
-
- 3. An int * (i.e. pointer) object which we can access through the identifier
- p e.g.
-
- p = NULL;
-
- 4. A value `address of object designated by i' in that object. An address
- isn't that useful unless we can reference what it points to, which is what
- the * operator allows us to do. e.g.
-
- *p = <expr>;
-
- * takes the value of a pointer as its operand and produces as its result
- an lvalue which designates what the operand pointed to. In the case above
- p points to the object that i designates, so *p and i designate the same
- object - they can be used interchangeably.
-
- The examples above show that context makes a difference to how things are
- treated in C. For example in:
-
- i = i + 1;
-
- i is in a context (the lhs of =) that requires an lvalue (in this case
- a modifiable lvalue) and in a context (an operand of +) that simply requires
- a value (call it an rvalue). How i is treated in these two contexts is
- clearly different. So now consider:
-
- int a[10] = { 0 };
-
- which defines an array of 10 integers and initialises each of them to 0.
- What we have here is a compound object - the array as a whole may be
- viewed as an object but so may each of its individual elements. a itself
- is an identifier which designates the entire array i.e. the 10 int objects
- viewed as a single unit. It has type (int [10]) and is purely and simply an
- array. In particular there is nothing pointerish about it at all here.
-
- It is considered that arrays are not 'first class' types in C - there is
- very little you can do to an array as a whole - you usually have to work
- on its elements. Some of the things you can do with arrays are:
-
- 1. Declare/define and initialise them
-
- 2. Take their address with &
-
- 3. Take their size with sizeof.
-
- The thing that C does not really support is the idea of an array 'value' (or
- more accurately a value with array type). For example you can't assign
- arrays (as you can even with structs), pass array typed arguments or in effect
- do anything to the contents of the array as a whole. However I can write:
-
- p = a;
-
- So what is happening here? C has a rule that if I try to take the value of
- an array (i.e. I place an expression that designates an array in a context
- that requires an 'rvalue') the compiler will give me a pointer to the
- first element of the array so:
-
- p = a;
-
- is equivalent to:
-
- p = &a[0];
-
-
- This doesn't mean that a is a pointer, only that it evaluates to a pointer
- in some (and certainly not all) circumstances. Just as with:
-
- const int j = 5;
-
- j is not the value 5 but does evaluate to it in circumstances where
- evaluation is required. *p and *a are lvalues which both designate the int
- object that is the first element of a, just as previously *p and i were
- lvalues that designated the same object.
-
- The oddity is that when evaluated an array lvalue does not generate a value
- (rvalue) that has array type.
-
- > Of course there are differences between arrays and pointers
- >due to the fact that an array is a CONSTANT address and a pointer is a
- >VARIABLE address.
-
- The reason that you can't simplify the above discussion down to saying
- that an array name is a pointer is that there are many contexts where it can
- appear where it does *not* evaluate to a pointer, e.g. declarations and as
- the operand of & or sizeof; basically any context that doesn't require
- an rvalue.
-
- I said at the start that pointers and arrays are (derived) types. As far as
- the type system itself goes there is no relation at all between arrays and
- pointers. When you define a pointer you are not reserving space for
- any form of array and similarly if you define an array you are not reserving
- space for any form of pointer (other than any pointers that may form part of
- its elements e.g. char *ap[100] an array of pointers to char).
-
- > And the reason I said you shouldn't (note shouldn't
- >not couldn't) say &myarray is:
-
- In ANSI C you can take the address of an array which is useful for dealing
- with arrays of arrays (loosely called 2D arrays). Prior to ANSI C it was
- a problem area.
-
- >(from "A Book On C", Kelley & Pohl, pg 200)
- >Constructs not to be pointed at:
- >1. Do not point at constants. (&3)
-
- You can't do that because 3 is not an lvalue. You can however take the
- address of j defined above.
-
- >2. Do not point at arrays; an array name is a constant. (int a[77]; &a)
-
- This is legal in ANSI C. The fact that it is in any sense constant is not
- relevant. The sense in which is constant is the same as the sense in which
- &i is constant - objects keep the same address for the duration of their
- lifetime (apart from possibly heap objects due to the unfortunate way in
- which realloc() is defined in the standard).
-
- >3. Do not point at ordinary expressions &(k + 99)
-
- + does not produce a result that is an lvalue.
-
- >4. Do not point at register variables. (register v; &v)
-
- That is really all register has come to mean - it is illegal to take its
- address.
-
- >So again I say, myarray is DEFINITELY a pointer (i.e. address in memory).
-
- That is only true in the one specific case where you are talking about the
- value of myarray in an rvalue context. It is not a generality.
-
- --
- -----------------------------------------
- Lawrence Kirby | fred@genesis.demon.co.uk
- Wilts, England | 70734.126@compuserve.com
- -----------------------------------------
-